import { ref, shallowRef, onScopeDispose } from 'vue'
import { ElMessage } from 'element-plus'
import { uploadImage as uploadImageApi } from '@/api/upload'

const defaultTypes = [
  'image/apng',
  'image/bmp',
  'image/gif',
  'image/jpeg',
  'image/pjpeg',
  'image/png',
  'image/svg+xml',
  'image/tiff',
  'image/webp',
  'image/x-icon'
]

export function useUpload(options) {
  const _uploader = document.createElement('input')
  _uploader.type = 'file'
  const uploader = shallowRef(_uploader)

  const url = ref(options?.url)
  const types = ref(options?.types ?? defaultTypes)
  const size = ref(options?.size ?? 5)
  const loading = ref(false)

  function select() {
    uploader.value.accept = types.value.toString()
    uploader.value.click()
  }

  function changedHandler() {
    const curFiles = uploader.value?.files
    const curFile = curFiles?.[0]

    curFile && upload(curFile)
  }

  async function upload(file) {
    if (!validFileType(file)) {
      return ElMessage.warning('不支持该文件类型')
    }

    if (!validFileSize(file)) {
      return ElMessage.warning('文件太大啦！')
    }

    const formData = new FormData()
    formData.set('file', file, file.name)
    loading.value = true

    try {
      const { data, code } = await uploadImageApi(formData)
      if (code === 200) {
        url.value = data.imageUrl

        return data.imageUrl
      } else {
        url.value = undefined
      }
    } finally {
      loading.value = false
      options?.onChange?.(url.value)
    }
  }

  function validFileType(file) {
    return types.value.includes(file.type)
  }

  function validFileSize(file) {
    return file.size < size.value * 1024 * 1024
  }

  function listenEvent() {
    uploader.value?.addEventListener('change', changedHandler)
  }

  listenEvent()
  onScopeDispose(() => (uploader.value = null))

  return {
    uploader,
    /**
     * 文件地址
     */
    url,
    /**
     * 文件类型
     */
    types: types.value.toString(),
    /**
     * 文件大小
     */
    size,
    /**
     * 上传方法
     */
    upload,
    select,
    loading,
    validFileType,
    validFileSize
  }
}
